package com.zxq.frame.msg.device;

import com.zxq.exchange.EFrame;
import com.zxq.exchange.ExchangeDTO;
import com.zxq.factory.FastFrame;
import com.zxq.frame.IEC104Frame;
import com.zxq.frame.crc.CrcUtils;
import com.zxq.memory.ByteArrayPools;
import com.zxq.memory.ByteCombination;
import com.zxq.tcp.cache.TcpChannelCache;
import com.zxq.tcp.handler.dispatch.TCPDispatchHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.xmlbeans.impl.util.HexBin;


@Slf4j
public class IEC104DispatchHandler extends TCPDispatchHandler<IEC104Frame> {

    /**
     * 第一个字节
     */
    final byte headFlag = (byte) 0xFF;

    /**
     * 第二个字节
     */
    final byte secondFlag = 0x18;



    @Override
    protected ExchangeDTO decodeExchangeDTO() {
        while (in.readableBytes() < 7) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        byte[] headBytes = ByteArrayPools.getBytes(7 + "");
        in.writeBytes(headBytes);
        int number1 = 0;
        int number2 = 0;
        if(headBytes[5] < 0) {
           number1 =  number1 + 256;
        }
        if(headBytes[6] < 0) {
            number2 =  number2 + 256;
        }
        Integer len =  number1 + number2 * 256;
        while (in.readableBytes() < len + 2) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        byte[] dataBuff = ByteArrayPools.getBytes(len + "");
        in.writeBytes(dataBuff);

        byte[] crcBuff = ByteArrayPools.getBytes(2 + "");
        in.writeBytes(crcBuff);

        byte[] waitCrcBuff = ByteCombination.combinationContent(headBytes,dataBuff);
        byte[] localCrcBuff =  CrcUtils.crc16(waitCrcBuff);
        if(crcBuff[0] == localCrcBuff[0] && crcBuff[1] == localCrcBuff[1]) {
            byte[] frame = ByteCombination.combinationContent(waitCrcBuff,crcBuff);
            IEC104Frame IEC104Frame = new IEC104Frame();
            FastFrame.decoder(IEC104Frame,frame);
            if(TcpChannelCache.getDevId(channel) == null) {
                log.info("error not find fyCharge:" + IEC104Frame.toString());
                return null;
            }
            ExchangeDTO exchangeDTO = new ExchangeDTO();

            exchangeDTO.setDevId(TcpChannelCache.getDevId(channel));
            String blockKey = IEC104Frame.getVersion() + IEC104Frame.getOpcode();
            exchangeDTO.setBlockKey(blockKey);
            exchangeDTO.setCmdHex(HexBin.bytesToString(new byte[]{ IEC104Frame.getOpcode()}));
            exchangeDTO.setFrame(EFrame.iec_104);
            exchangeDTO.setData(IEC104Frame.getDataFrame());

            return exchangeDTO;
        }

        log.info("crc is error!");
        return null;
    }

    @Override
    protected IEC104Frame produceFrame(String cmd_id, byte[] data) {
        return null;
    }

    @Override
    protected EFrame getTcpFrame() {
        return EFrame.iec_104;
    }

    @Override
    public boolean isThisFrame() {
       byte head = in.readByte();
       byte second = in.readByte();
       in.resetReaderIndex();
       if((head == headFlag) && (second == secondFlag)) {
           return true;
       }
       return false;
    }
}
